import { HttpClient, HttpHeaders, HttpParams, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError, of } from 'rxjs';
import { filter, catchError } from 'rxjs/operators';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { APP_CONFIG } from '@env/environment';
import * as qs from 'qs';
export interface ActionResult {
  code: number;
  msg: string;
  data: any;
}

@Injectable({
  providedIn: 'root'
})
export class BaseHttpService {
  uri: string;

  protected constructor(public http: HttpClient) {
    this.uri = APP_CONFIG.baseApi;
  }

  get(path: string, param?: NzSafeAny, config?: object): Observable<NzSafeAny> {
    const params = new HttpParams({ fromString: qs.stringify(param) });
    const options = { params, ...config };
    const url = this.uri + path;
    return this.http.get<ActionResult>(url, options).pipe(
      filter(item => this.handleFilter(item)),
      catchError(this.handleError)
    );
  }

  delete(path: string, param?: NzSafeAny, config?: object): Observable<NzSafeAny> {
    const params = new HttpParams({ fromString: qs.stringify(param) });
    const options: object = { params, ...config };
    const url: string = this.uri + path;
    return this.http.delete<ActionResult>(url, options).pipe(
      filter(item => this.handleFilter(item)),
      catchError(this.handleError)
    );
  }

  post(path: string, param?: NzSafeAny, config?: object): Observable<NzSafeAny> {
    const options: object = { ...config };
    const url: string = this.uri + path;
    return this.http.post<ActionResult>(url, param, options).pipe(
      filter(item => this.handleFilter(item)),
      catchError(this.handleError)
    );
  }

  put(path: string, param?: NzSafeAny, config?: object): Observable<NzSafeAny> {
    const options: object = { ...config };
    const url: string = this.uri + path;
    return this.http.put<ActionResult>(url, param, options).pipe(
      filter(item => this.handleFilter(item)),
      catchError(this.handleError)
    );
  }

  downZip(path: string, param?: NzSafeAny, config?: object): Observable<NzSafeAny> {
    const defaultObj: object = {
      responseType: 'blob',
      headers: new HttpHeaders().append('Content-Type', 'application/json')
    };
    const url: string = this.uri + path;
    const options = Object.assign(defaultObj, config);
    return this.http.post(url, param, options).pipe(
      catchError(this.handleError)
    );
  }

  handleFilter(item: ActionResult): boolean {
    //todoo...
    return true;
  }

  handleError(error: HttpErrorResponse) {
    console.error('handleError', error);
    //抛出异常，界面可以再次catch来个性化处理
    throwError(() => new Error(error.message))
    //继续执行
    return of(error);
  }

}
